package com.ruge.tools.antisamy.starter;

import com.ruge.tools.antisamy.starter.converter.XssStringJsonDeserializer;
import com.ruge.tools.antisamy.starter.filter.XssFilter;
import com.ruge.tools.antisamy.starter.properties.XssProperties;
import org.apache.tomcat.util.buf.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;

/**
 * description XSS 跨站攻击自动配置
 * create Time at 2022/8/26 10:40
 *
 * @author alice.ruge
 * @since 0.0.7
 */
@Configuration
@EnableConfigurationProperties(XssProperties.class)
public class XssAuthConfig {

    @Resource
    private XssProperties xssProperties;

    /**
     * 配置跨站攻击 反序列化处理器
     *
     * @return {@link Jackson2ObjectMapperBuilderCustomizer}
     */
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer2() {
        return builder -> builder
                .deserializerByType(String.class, new XssStringJsonDeserializer());
    }

    /**
     * 配置跨站攻击过滤器
     *
     * @return {@link XssFilter}
     */
    @Bean
    @ConditionalOnProperty(name = "ruge.xss.enable", havingValue = "true", matchIfMissing = true)
    public FilterRegistrationBean<XssFilter> filterRegistrationBean() {
        //TODO 想想这里如何扩展
        FilterRegistrationBean<XssFilter> bean = new FilterRegistrationBean<>();
        //注册自定义过滤器
        bean.setFilter(new XssFilter());
        //过滤所有路径
        bean.addUrlPatterns("/*");
        //优先级，最顶级
        bean.setOrder(1);

        Map<String, String> initParameters = new HashMap<>(2);
        String excludes = new StringJoiner(",")
                .add("/favicon.ico")
                .add("/doc.html")
                .add("/swagger-ui.html")
                .add("/csrf")
                .add("/webjars/*")
                .add("/v2/*")
                .add("/swagger-resources/*")
                .add("/resources/*")
                .add("/static/*")
                .add("/public/*")
                .add("/classpath:*")
                .add("/actuator/*")
                .toString();
        initParameters.put("excludes", excludes);
        initParameters.put("isIncludeRichText", "true");
        initParameters.put("ignorePath", StringUtils.join(xssProperties.getIgnorePath(), ','));
        bean.setInitParameters(initParameters);
        return bean;
    }
}
